package com.example.demo.design;

/**
 * 模板方法模式:设计一个抽象父类，父类中定义了主要的逻辑方法和数据结构，扩展定义多个子类继承抽象父类，
 * 子类重写(@Override)父类的protected修饰的抽象方法，根据业务需求的变化实现这些抽象方法，但大致的代码逻辑由抽象父类定义，
 * 符合开闭原则（封装不变部分，扩展可变部分）
 */
public abstract class StrategyTemplate {
    private String a = getA();
    protected String b;

    // 钩子函数，变化部分由子类实现
    protected abstract String getA();
    protected abstract void method1();
    protected abstract void method2();
    // 主要逻辑由父类实现
    // 模板方法模式只针对一套算法
    public void method() {
        // logic
        method1();
        method2();
        // ...
    }
    
}

class A extends StrategyTemplate {

    @Override
    protected String getA() {
        return "abc";
    }

    @Override
    protected void method1() {
        System.out.println("A.method1()");
    }

    @Override
    protected void method2() {
        System.out.println("A.method2()");
    }
}

class B extends StrategyTemplate {

    @Override
    protected String getA() {
        return "def";
    }

    @Override
    protected void method1() {
        System.out.println("B.method1()");
    }

    @Override
    protected void method2() {
        System.out.println("B.method2()");
    }
}

class Test {
    public static void main(String[] args) {
        StrategyTemplate st = new A();
        st.method();
        st = new B();
        st.method();
    }
}
